package com.llmcu.trial.completablefuture;


import lombok.extern.slf4j.Slf4j;

import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

@Slf4j
public class CompletableFutureTaskExample {

    public static void main(String[] args) throws InterruptedException {
        log.info("program start========");
        // 定义任务
        Runnable task = () -> {
            Random random = new Random();
            int seconds = random.nextInt(8);
            try {
                TimeUnit.SECONDS.sleep(seconds + 1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            log.info("Task [{}] completed after {} seconds*********************", Thread.currentThread().getName(), seconds + 1);

        };

        // 创建多个 CompletableFuture 来并行执行任务
        CompletableFuture<Void> future1 = CompletableFuture.runAsync(task);
        CompletableFuture<Void> future2 = CompletableFuture.runAsync(task);
        CompletableFuture<Void> future3 = CompletableFuture.runAsync(task);

        Runnable secondTask = () -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            log.info("task[{}] completed...................", Thread.currentThread().getName());
        };
        future1 = future1.thenRun(secondTask);
        future2 = future2.thenRun(secondTask);
        future3 = future3.thenRun(secondTask);

        // 将所有异步任务组合在一起，并等待它们完成
//        CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2, future3);
        CompletableFuture<Object> allFutures = CompletableFuture.anyOf(future1, future2, future3);

        // 当所有任务都完成时，执行一些操作
        allFutures.thenRun(() -> log.info("all tasks completed***************"));

        // 等待所有任务完成（阻塞主线程）
        try {
            allFutures.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        // 如果没有上面的`allFutures.get();`,主线程是立马执行下面的代码
        log.info("main thread start waiting===========");
//        默认情况下，CompletableFuture.runAsync() 使用的是 ForkJoinPool.commonPool()，其线程是 守护线程（daemon）。所以主线程要等待其完成
        TimeUnit.SECONDS.sleep(10);
        log.info("main thread completed============");
    }

}
